using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Comdiv.Extensions;
using Comdiv.Inversion;
using System.Web.Routing;

namespace MvcContrib.Comdiv.Framework
{

    

    public class InversionControllerFactory:DefaultControllerFactory, IWithContainer
    {
        public IInversionContainer Container { get; set; }
        IDictionary<string,Type> resolvecache = new Dictionary<string, Type>();
        protected override Type GetControllerType(RequestContext ctx, string controllerName)
        {
            controllerName = controllerName.ToLower();
            return resolvecache.get(controllerName, () =>{
                                                        var all = Container.all<IController>();
                                                        try{
                                                            var byname =
                                                                Container.Resolve(controllerName + ".controller");
                                                            if (null != byname){
                                                                return byname.GetType();
                                                            }
                                                        }catch{
                                                            
                                                        }
                                                        foreach (var controller in all){
                                                            var name = controller.GetType().Name.ToLower();
                                                            if (name == (controllerName.ToLower() + "controller")){
                                                                return controller.GetType();
                                                            }

                                                        }
                                                        var defaultResult = base.GetControllerType(ctx,controllerName);

                                                        if (null != defaultResult){
                                                            Container.AddTransient(controllerName + ".controller",
                                                                               defaultResult);
                                                            return defaultResult;

                                                        }

                                                        
                                                        
                                                        throw new Exception(
                                                            "cannot find type for controller with name '" +
                                                            controllerName + "'");


                                                    });
        }

        protected override IController GetControllerInstance(RequestContext ctx, Type controllerType)
        {
            
            return (IController)Container.Resolve(controllerType);
        }
       
    }
}
